package com.ijecorp.media.riff;


/**
 * @author Miller Lai
 * @since 2007/12/30
 * @see http://netghost.narod.ru/gff/graphics/summary/micriff.htm
 * @description 
<P>
 
 
Microsoft RIFF (Resource Interchange File Format) is a multimedia file format
created by Microsoft for use with the Windows GUI. 
 
RIFF itself does not define
any new methods of storing data, as many of the bitmap formats described in
this book do. Instead, RIFF defines a structured framework, which may contain
existing data formats. Using this concept, you can create new, composite
formats consisting of two or more existing file formats.


<P>
<B>Contents:</B><br>
<A HREF="#MICRIFF-DMYID.2">File Organization</A><br>
<A HREF="#MICRIFF-DMYID.3">File Details</A><br>
<A HREF="#MICRIFF-DMYID.4">For Further Information</A><br>

<P>
Multimedia applications require the storage and management of a wide variety of
data, including bitmaps, audio data, video data, and peripheral device control
information. RIFF provides an excellent way to store all these varied types of
data. The type of data a RIFF file contains is indicated by the file extension.
Examples of data that may be stored in RIFF files are:
 
<p><ul>

<li>Audio/visual interleaved data (.AVI)

<P>

<li>Waveform data (.WAV)

<P>

<li>Bitmapped data (.RDI)

<P>

<li>MIDI information (.RMI)

<P>

<li>A bundle of other RIFF files (.BND)

<P>
</ul><p>
<P><BLOCKQUOTE><b>NOTE: 

<P>
 
At this point, AVI files are the only type of RIFF files that have been
fully implemented using the current RIFF specification. Although WAV files
have been implemented, these files are very simple, and their developers
typically use an older specification in constructing them.</b></blockquote><P>
<P>
Because RIFF is an umbrella name for a variety of multimedia files, 
RIFF files
are referred to by the type of data they contain, rather than by the actual
format name of RIFF. For this reason, you may find RIFF files rather
confusing when you start to use them. For example, a RIFF file containing
Audio/Visual Interleaved data is normally referred to simply as an "AVI file"
and not as a "RIFF Audio/Visual Interleaved Format File." Only a programmer
might ever realize that all of these different files are the same format, or
even care.

<P>
There is another area of potential confusion. Some people think that RIFF files
are somehow similar in design to TIFF (Tag Image File Format) files. While it
is true that both formats contain data structures that may be added or deleted
to a file ("tags" in TIFF and "chunks" in RIFF), 
 
the internal concept and
design of these structures within RIFF and TIFF differ greatly. Unlike TIFF,
the RIFF file format is based on the Electronic Arts Interchange File Format
 
(IFF) structure (see <A HREF="iff.htm">the article</A> describing this format). And, although both
formats use the same concept of data storage, they are not compatible in their
design.

<h2><A NAME="MICRIFF-DMYID.2">File Organization</A></h2>

<P>
RIFF is a binary file format containing multiple nested data structures. Each
data structure within a RIFF file is called a <i>chunk</i>. 
 
Chunks do not have
fixed positions within a RIFF file, and therefore standard offset values cannot
be used to locate their fields. A chunk contains data such as a data structure,
a data stream, or another chunk called a <i>subchunk</i>. Every RIFF chunk has
the following basic structure:
<pre>
typedef struct _Chunk
{
    DWORD ChunkId;              // Chunk ID marker 
    DWORD ChunkSize;            // Size of the chunk data in bytes 
    BYTE ChunkData[ChunkSize];  // The chunk data 
} CHUNK;
</pre>
<P>
ChunkId contains four ASCII characters that identify the data the chunk
contains. For example, the characters RIFF are used to identify chunks
containing RIFF data. If an ID is smaller than four characters, it is padded on
the right using spaces (ASCII 32). Note that RIFF files are written in
little-endian byte order. Files written using the big-endian byte ordering
scheme have the identifier RIFX.

<P>
ChunkSize is the length of the data stored in the ChunkData field, not
including any padding added to the data. The size of the ChunkId and ChunkSize
fields are not themselves included in this value.

<P>
ChunkData contains data that is WORD-aligned within the RIFF file. If the data
is an odd length in size, an extra byte of NULL padding is added to the
end of the data. The ChunkSize value does not include the length of the
padding.

<P>
Subchunks also have the same structure as chunks. A subchunk is simply any
chunk that is contained within another chunk. The only chunks that may contain
subchunks are the RIFF file chunk RIFF and the list chunk, LIST (explained
in the next section). All other chunks may contain only data.

<P>
A RIFF file itself is one entire RIFF chunk. All other chunks and subchunks in
the file are contained within this chunk. If you are decoding, your
RIFF reader
 
should ignore any chunks that the reader does not recognize or it cannot use.
If you are encoding, your RIFF writer will write out all unknown and unused
chunks that were read. Do not discard them.

<h2><A NAME="MICRIFF-DMYID.3">File Details</A></h2>

<P>
RIFF files that are used to store audio and video information are called AVI
files. 
The RIFF AVI file format normally contains only a single AVI chunk;
however, other types of chunks may also appear. An AVI reader should ignore all
chunks it does not need or recognize that are stored within a RIFF AVI file.

<P>
Although Microsoft uses a standard notation to describe the internal
arrangement of data structures within RIFF files, we believe it is clearer to
use our own C-like syntax to illustrate the placement of chunks and subchunks
within a RIFF AVI file. The ChunkId for each chunk is listed in the comments:
<pre>
struct _RIFF   /* "RIFF" 
{
    struct _AVICHUNK   /* "AVI " 
    {
        struct _LISTHEADERCHUNK   /* "hdrl" 
        {
            AVIHEADER AviHeader;     /* "avih" 
            struct _LISTHEADERCHUNK  /* "strl" 
            {
                AVISTREAMHEADER	StreamHeader; /* "strh" 
                AVISTREAMFORMAT	StreamFormat; /* "strf" 
                AVISTREAMDATA	StreamData;   /* "strd" 
            }
        }
        struct _LISTMOVIECHUNK  /* "movi" 
        {
            struct _LISTRECORDCHUNK  /* "rec " 
            {
                /* Subchunk 1 
                /* Subchunk 2 
                /* Subchunk N 
            }
        }
        struct _AVIINDEXCHUNK  /* "idx1" 
        {
            /* Index data 
        }
    }
}
</pre>
<P>
The above structure represents the internal data layout of a RIFF file
containing only one AVI chunk. This chunk follows the format of the chunk data
structure previously described. The AVI chunk is identified by the
4-character chunk identifier "AVI " (note the final blank character). The
AVI chunk contains two mandatory LIST subchunks, which indicate the format of
the data stream(s) stored in the file.

<h3><A NAME="MICRIFF-DMYID.3.1">AVI Header Subchunk</A></h3>

<P>
The first mandatory LIST chunk contains the main AVI header subchunk and has
the identifier hdrl. The information in the header subchunk defines the
format of the entire AVI chunk. The hdrl chunk must appear as the first chunk
within the AVI chunk. The format of the header subchunk is the following:
<pre>
typedef struct _AVIHeader
{
    DWORD TimeBetweenFrames;     // Time delay between frames 
    DWORD MaximumDataRate;       // Data rate of AVI data 
    DWORD PaddingGranularity;    // Size of single unit of padding 
    DWORD Flags;                 // Data parameters 
    DWORD TotalNumberOfFrames;   // Number of video frame stored 
    DWORD NumberOfInitialFrames; // Number of preview frames 
    DWORD NumberOfStreams;       // Number of data streams in chunk
    DWORD SuggestedBufferSize;   // Minimum playback buffer size 
    DWORD Width;                 // Width of video frame in pixels 
    DWORD Height;                // Height of video frame in pixels
    DWORD TimeScale;             // Unit used to measure time 
    DWORD DataRate;              // Data rate of playback 
    DWORD StartTime;             // Starting time of AVI data 
    DWORD DataLength;            // Size of AVI data chunk 
} AVIHEADER;
</pre>
<P>
TimeBetweenFrames contains a value indicating the amount of delay between
frames in microseconds.

<P>
MaximumDataRate value indicates the data rate of the AVI data in bytes
per second.

<P>
PaddingGranularity specifies the multiple size of padding used in the data in
bytes. When used, the value of this field is typically 2048.

<P>
Flags contains parameter settings specific to the AVI file and its data. The
parameters correspond to the bit values of the Flags field as follows:
<p><dl>
<DT>Bit 4<DD>

<P>
AVI chunk contains an index subchunk (idx1).

<p>
<DT>Bit 5<DD>

<P>
Use the index data to determine how to read the AVI data, rather than
the physical order of the chunks with the RIFF file.

<p>
<DT>Bit 8<DD>

<P>
AVI file is interleaved.

<p>
<DT>Bit 16<DD>

<P>
AVI file is optimized for live video capture.

<p>
<DT>Bit 17<DD>

<P>
AVI file contains copyrighted data.</dl><p>
<P>
TotalNumberOfFrames indicates the total number of frames of video data stored
in the movi subchunk.

<P>
NumberOfInitialFrames specifies the number of frames in the file before the
actual AVI data. For non-interleaved data this value is 0.

<P>
NumberOfStreams holds the number of data streams in the chunk. A file with an
audio and video stream contains a value of 2 in this field, while an AVI file
containing only video data has 1. In the current version of the RIFF format,
one audio and one video stream are allowed.

<P>
SuggestedBufferSize is the minimum size of the buffer to allocate for playback
of the AVI data. For non-interleaved AVI data, this value is at least the size
of the largest chunk in the file. For interleaved AVI files, this value should
be the size of an entire AVI record.

<P>
Width and Height values indicate the size of the video image in pixels.

<P>
TimeScale is the unit used to measure time in this chunk. It is used with
DataRate to specify the time scale that the stream will use. For video
streams, this value should be the frame rate and typically has a value of 30.
For audio streams, this value is typically the audio sample rate.

<P>
DataRate is divided by the TimeScale value to calculate the number of samples
per second.

<P>
StartTime is the starting time of the AVI data and is usually 0.

<P>
DataLength is the size of the AVI chunk in the units specified by the TimeScale
value.

<P>
The hdrl subchunk also contains one or more LIST chunks with the identifier
strl. There will be one of these LIST chunks per data stream stored in the
AVI chunk.

<P>
Three subchunks are stored within the strl LIST chunk. The first is the
Stream Header subchunk, which has the identifier strh. This header contains
information specific to the data stream stored in the strl LIST chunk. A
stream header is required and has the following format:
<pre>
typedef struct _StreamHeader
{
    char  DataType[4];           // Chunk identifier ("strl") 
    char  DataHandler[4];        // Device handler identifier 
    DWORD Flags;                 // Data parameters 
    DWORD Priority;              // Set to 0 
    DWORD InitialFrames;         // Number of initial audio frames 
    DWORD TimeScale;             // Unit used to measure time 
    DWORD DataRate;              // Data rate of playback 
    DWORD StartTime;             // Starting time of AVI data 
    DWORD DataLength;            // Size of AVI data chunk 
    DWORD SuggestedBufferSize;   // Minimum playback buffer size 
    DWORD Quality;               // Sample quailty factor 
    DWORD SampleSize;            // Size of the sample in bytes 
} STREAMHEADER;
</pre>
<P>
DataType contains a 4-character identifier indicating the type of data the
stream header refers to. Identifiers supported by the current version of the
RIFF format are: vids for video data and auds for audio data.

<P>
DataHandler may contain a 4-character identifier specifying the preferred
type of device to handle the data stream.

<P>
Flags contains a set of bit flags use to indicate parameter settings related to
the data.

<P>
Priority is set to 0.

<P>
InitialFrames indicates in seconds how far the audio is placed ahead of the
video in interleaved data.

<P>
TimeScale, DataRate, StartTime, DataLength, and SuggestedBufferSize all have
the same function as the fields of the same names in the hdr1 chunk.

<P>
Quality is an integer in the range of 0 to 10,000, indicating the quality factor
used to encode the sample.

<P>
SampleSize is the size of a single sample of data. If this value is 0, the
sample varies in size and each sample is stored in a separate subchunk. If this
value is non-zero, then
all the samples are the same size and are stored in a
single subchunk.

<P>
Immediately following the stream header is a stream format subchunk with the
identifier strf. This header describes the format of the stream data. Its
format varies depending on the type of data that is stored (audio or video).
This subchunk is also required.

<P>
Another stream data subchunk with the identifier strd can optionally follow
the stream format subchunk. The data in this chunk is used to configure the
drivers required to interpret the data. The format of this chunk also varies
depending upon the type of compression used on the stream data.

<h3><A NAME="MICRIFF-DMYID.3.2">AVI Data Subchunk</A></h3>

<P>
The second mandatory LIST chunk contains the actual AVI data, has the
identifier movi, and must appear as the second chunk within the AVI chunk.

<P>
The data in the movi chunk may be grouped in the form of LIST records (a LIST
chunk containing one or more subchunks each with the identifier "rec "). Only
data that is interleaved to be read from a CD-ROM is stored as a series of LIST
records (data is read more efficiently from a CD-ROM when it is interleaved).
If the data is not interleaved, it is stored as a single block of data within
the movi chunk itself.

<h3><A NAME="MICRIFF-DMYID.3.3">Index Chunk</A></h3>

<P>
The AVI chunk may also contain a third chunk, called an index chunk. An
index chunk has the identifier idx1 and must appear after the hdrl and
movi chunks. This chunk contains a list of all chunks within the AVI chunk,
along with their locations, and is used for random access of audio and video
data. The index chunk has the following format:
<pre>
typedef struct _AviIndex
{
    DWORD Identifier;    // Chunk identifier reference 
    DWORD Flags;         // Type of chunk referenced 
    DWORD Offset;        // Position of chunk in file 
    DWORD Length;        // Length of chunk in bytes 
} AVIINDEX;
</pre>
<P>
Identifier contains the 4-byte identifier of the chunk it references
(strh, strf, strd, and so on).

<P>
Flags bits are used to indicate the type of frame the chunk contains
or to
identify the index structure as pointing to a LIST chunk.

<P>
Offset indicates the start of the chunk in bytes relative to the movi list
chunk.

<P>
Length is the size of the chunk in bytes.

<P>
The idx1 chunk contains one of these structures for every chunk and subchunk
in the AVI chunk. The structures need not index each chunk in the order in
which they occur within the AVI chunk. The order of the index structures in
the idx1 may also be used to control the presentation order of the data
stored in the AVI chunk. If an index is included in an AVI chunk, the
appropriate indication bit must be set in the Flags field of the AVI
header chunk. If an application reading a RIFF file decides to use the information in
the index chunk, it must first find the hdrl chunk and determine if an index
chunk exists by examining the Flags field value in the AVI header. If it
does exist, the reader will skip past all the chunks in the AVI chunk until it
encounters the idx1 chunk.

<h3><A NAME="MICRIFF-DMYID.3.4">JUNK Chunk</A></h3>

<P>
One other type of chunk that is commonly encountered in an AVI chunk is the
padding or JUNK chunk (so named because its chunk identifier is JUNK). This
chunk is used to pad data out to specific boundaries (for example, CD-ROMs use
2048-byte boundaries). The size of the chunk is the number of bytes of padding
it contains. If you are reading AVI data, do not use use the data in the JUNK
chunk. Skip it when reading and preserve it when writing. The JUNK chunk uses
the standard chunk structure:
<pre>
typedef struct _JunkChunk
{
    DWORD ChunkId;             // Chunk ID marker (JUNK)
    DWORD PaggingSize;         // Size of the padding in bytes 
    BYTE Padding[ChunkSize];   // Padding 
} JUNKCHUNK;
</pre>
*/

//[ A RIFF file itself is one entire RIFF chunk. All other chunks and subchunks in 
//[ the file are contained within this chunk. If you are decoding, your RIFF reader 
//[ should ignore any chunks that the reader does not recognize or it cannot use. 
//[ If you are encoding, your RIFF writer will write out all unknown and unused chunks 
//[ that were read. Do not discard them
//[ RIFF Spec: http://netghost.narod.ru/gff/vendspec/micriff/ms_riff.txt
public class RIFFChunk {

	public final static int RIFF_ID = 0x52494646; //: RIFF 
	//: RIFF files are written in little-endian byte order
//	public static final String RIFF = "RIFF"; 
	//: Files written using the big-endian byte ordering scheme have the identifier RIFX. 
//	public static final String RIFX = "RIFX"; 
	

	protected final int chunkID;
	protected final int chunkSize;
	
	public RIFFChunk(int ID, int size){
		this.chunkID = ID;
		this.chunkSize = size;
	}	
}



